package ms.jasim.framework;

import ms.jacrim.pddl.PddlSolution;
import ms.jacrim.pddl.PddlSolution.Action;
import ms.jacrim.pddl.PddlSolution.Functor;
import ms.spm.IAppContext;

@IEvaluator.Info(Name = "Cost/Benefit Quotient", Description = "", Components = { "Value", "Benefit", "Cost" })
public class CBQEvaluator implements IEvaluator {

	private final float DEFAULT_COST = .0f;
	
	float score = Float.NaN;
	float benefit = Float.NaN;
	float cost = Float.NaN;
	
	
	@Override
	public EvaluatorResult evaluate(IAppContext context, PddlModel model, Iterable<Action> actions) {
		
		cost = benefit = 0;
		
		for (PddlSolution.Action a : actions) {
			if (a.getFunctor() == Functor.SATISFIES) {
				PddlModel.Actor act = model.Actors.get(a.Argument(0));
				PddlModel.Capacity cap = act.Capacity.get(a.Argument(1));
				
				if (cap != null) {
					cost += cap.getEffort();
					benefit += cap.getSatisfaction();
				}
			} else
				cost += DEFAULT_COST;
		}

		score = cost * model.getWorkloadCoeff() != 0 ? (benefit * model.getSatCoeff()) / (cost * model.getWorkloadCoeff())
				: Float.NaN;
		
		return new EvaluatorResult(CBQEvaluator.class, new float[] { score, benefit, cost });
	}


	@Override
	public EvaluatorResult combine(EvaluatorResult a, EvaluatorResult b) {
		EvaluatorResult result = a.clone();
		result.setValue(1, result.getValue(1) + b.getValue(1));
		result.setValue(2, result.getValue(2) + b.getValue(2));
		result.setValue(0, result.getValue(1) / result.getValue(2));
		return result;
	}

}
